﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Multiprocessing.Core.Mathematics.Graphs
{
    public interface IGraph<TNodeKey, TNodeValue, TRibValue>
        : IEnumerable<GraphNode<TNodeKey, TNodeValue, TRibValue>>
    {
        void Add(TNodeKey key, TNodeValue value);
        void Add(GraphNode<TNodeKey, TNodeValue, TRibValue> node);
        bool TryGetValue(TNodeKey key, out GraphNode<TNodeKey, TNodeValue, TRibValue> node);
        GraphNode<TNodeKey, TNodeValue, TRibValue> this[TNodeKey key] { get; set; }
        int Count { get; }
        IEnumerable<DirectionalRib<TNodeKey, TNodeValue, TRibValue>> Ribs { get; }

        void AddRib(GraphNode<TNodeKey, TNodeValue, TRibValue> @from, GraphNode<TNodeKey, TNodeValue, TRibValue> @to,
                    TRibValue weight);

        void AddRib(TNodeKey from, TNodeKey to, TRibValue weight);

        bool RemoveNode(TNodeKey key);

        bool RemoveRib(TNodeKey first, TNodeKey second);
        bool RemoveRib(GraphNode<TNodeKey, TNodeValue, TRibValue> first,
                       GraphNode<TNodeKey, TNodeValue, TRibValue> second);

        DirectionalRib<TNodeKey, TNodeValue, TRibValue> GetRib(GraphNode<TNodeKey, TNodeValue, TRibValue> first,
                                                               GraphNode<TNodeKey, TNodeValue, TRibValue> second);
        DirectionalRib<TNodeKey, TNodeValue, TRibValue> GetRib(TNodeKey first, TNodeKey second);

        bool TryGetRib(GraphNode<TNodeKey, TNodeValue, TRibValue> first,
                       GraphNode<TNodeKey, TNodeValue, TRibValue> second,
                       out DirectionalRib<TNodeKey, TNodeValue, TRibValue> rib);

        bool TryGetRib(TNodeKey first, TNodeKey second, out DirectionalRib<TNodeKey, TNodeValue, TRibValue> rib);
        void Clear();
    }
}
